package com.dylan.channel.v7.channel;

import com.dylan.channel.v7.EventLoop;
import com.dylan.channel.v7.future.ChannelFuture;
import com.dylan.channel.v7.future.ChannelPromise;

import java.net.SocketAddress;

public abstract class AbstractChannel implements Channel {
    private volatile EventLoop eventLoop;

    private final Channel parent;

    /**
     * @Author: PP-jessica
     * @Description:该channel是否注册过
     */
    private volatile boolean registered;

    protected AbstractChannel(Channel parent) {
        this.parent = parent;
    }

    @Override
    public EventLoop eventLoop() {
        EventLoop eventLoop = this.eventLoop;
        if (eventLoop == null) {
            throw new IllegalStateException("channel not registered to an event loop");
        }
        return eventLoop;
    }

    @Override
    public void register(EventLoop eventLoop, ChannelPromise promise) {
        //断言eventLoop是否为空
        assert eventLoop != null;

        //断言未注册过
        assert !isRegistered();

        this.eventLoop = eventLoop;

        if (eventLoop.inEventLoop(Thread.currentThread())) {
            register0(promise);
        } else {
            eventLoop.execute(new Runnable() {
                @Override
                public void run() {
                    register0(promise);
                }
            });
        }
    }

    @Override
    public boolean isRegistered() {
        return registered;
    }

    protected abstract void doRegister();


    private void register0(ChannelPromise promise) {

        //开始执行真正得注册逻辑
        doRegister();

        registered = true;

        //将异步结果设置成成功
        promise.setSuccess(null);
    }

    @Override
    public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
        try {
            doBind(localAddress);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected abstract void doBind(SocketAddress localAddress) throws Exception;

}
